import { ZegoLyricView } from "./lyricView/dist/ZegoLyricView.browser";
import { ZegoPitchView } from "./pitchView/dist/ZegoPitchView.browser";
import {
  localStreamMap,
  publishStreamId,
  enterRoom,
  zg
} from '../../common';

let publishState = "NO_PUBLISH"

function getEngine() {
  const { zg } = window;
  if (!zg) {
    throw alert("not init");
  }
  return zg;
}
function getZCM() {
  const engine = getEngine();
  const cm = engine.createCopyrightedMusic();
  if (!cm) {
    throw alert("版权音乐初始化失败");
  }
  return cm;
}
export async function copyMusic() {
  await new Promise(resolve => {
    $("#copyMusicPanne").load("./copyMusic/index.html", resolve);
  });
  console.log("zc.cm 载入 copyMusicPanne");
  // 初始化歌词组件
  const lyricView = new ZegoLyricView();
  lyricView.mount("lyricsPlayer", {
    highLightFontColor: "#0fdd7a",
    defaultFontColor: "#cb57f7",
    highLightFontSize: 18,
    defaultFontSize: 12
  });
  lyricView.setCustomDefaultFontStyle("filter: drop-shadow(2px 4px 6px #0000)");
  lyricView.setCustomHighLightFontStyle("filter: drop-shadow(2px 4px 6px #0fdd7a)");
  lyricView.setCustomLineStyle("display: flex; justify-content: center;");
  let krcTimer;
  const interTime = 100;

  // 初始化音高线组件
  const pitchView = new ZegoPitchView();
  let pitchTimer;
  const pitchInterTime = 100;
  let isScoreRunning = false;
  let isScorePaused = false;
  let fullScore = 0;

  pitchView.onPlayLineChange = async (currentIndex) => {
    const resourceID = $("#pitchResourceID").val();
    const zcm = getZCM();
    const total = await zcm.getTotalScore(resourceID);
    const average = await zcm.getAverageScore(resourceID);
    const preScore = await zcm.getPreviousScore(resourceID);
    $("#scoreInfo").text(
      `满分：${fullScore}, 总分：${total}, 平均分：${average}, 上句分: ${preScore}
        暂停：${isScorePaused}, 打分中：${isScoreRunning}
      `
    );
    if (currentIndex >= 1) {
      pitchView.addScore(preScore);
    }
  };

  // 绑定播放器
  const songPlayer = document.getElementById("copySongPlayer");
  const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
  function debounce(func, delay) {
    let timer = null;
    return function () {
      const context = this;
      const args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
        func.apply(context, args);
      }, delay);
    }
  }
  songPlayer.addEventListener("seeked", debounce(() => {
    console.warn("songPlayer seeked", songPlayer.currentTime)
    if (Math.abs(accompanyPlayer.currentTime - songPlayer.currentTime) > 0.5) {
      accompanyPlayer.currentTime = songPlayer.currentTime;
    }
  }, 500));
  accompanyPlayer.addEventListener("seeked", debounce(() => {
    console.warn("accompanyPlayer seeked", accompanyPlayer.currentTime)
    if (Math.abs(accompanyPlayer.currentTime - songPlayer.currentTime) > 0.5) {
      songPlayer.currentTime = accompanyPlayer.currentTime;
    }
  }, 500));
  function handleLyrics(lyrics) {
    lyricView.setupLyric(lyrics);
    // lyricView.autoplayKrc();
    if (krcTimer)
      clearInterval(krcTimer);
    krcTimer = setInterval(() => {
      if (!songPlayer.paused) {
        lyricView.setCurrentTimeMillis(songPlayer.currentTime * 1000);
        const info = {
          KEY_PROCESS_IN_MS: songPlayer.currentTime,
          KEY_Total_IN_MS: songPlayer.duration
        };
        if (publishState === "PUBLISHING") {
          // console.log("zc.cm 发送SEI ",info)
          const res = getEngine().sendSEI(publishStreamId, new TextEncoder().encode(JSON.stringify(info)));
        }
      }
    }, interTime);
  }
  // 处理打分
  let curPitch = [];
  function handlePitch(pitch) {
    if (pitch) {
      curPitch = pitch;
    }
    const zcm = getZCM();
    const resourceID = $("#pitchResourceID").val();
    pitchView.mount("pitchView");
    pitchView.setStandardPitch(curPitch);
    if (pitchTimer) clearInterval(pitchTimer);
    pitchTimer = setInterval(async () => {
      if (!songPlayer.paused && pitchView) {
        const value = await zcm.getCurrentPitch(resourceID);
        pitchView.setCurrentSongProgress(songPlayer.currentTime * 1000, value);
      }
    }, pitchInterTime);
    // player.autoplayKrc();
  }

  const getPitchFunc = async (rId) => {
    const zcm = getZCM();
    const { errorCode, pitch } = await zcm.getStandardPitch(rId);
    console.warn("getPitchData", { errorCode, pitch });
    if (errorCode === 0) {
      handlePitch(pitch);
    } else {
      alert("get pitch failed. " + errorCode);
    }
  };
  $("#getPitchData").on("click", async () => {
    await getPitchFunc($("#pitchResourceID").val());
  });
  async function startScore(resourceID) {
    const zcm = getZCM();
    const localPublishStream = localStreamMap[$("#roomId").val()]
    if (localPublishStream) {
      zcm.startScore(localPublishStream, songPlayer, resourceID);

      fullScore = await zcm.getFullScore(resourceID);
      pitchView.onPlayLineChange(0, 0);
      isScoreRunning = true;
      isScorePaused = false;
    } else alert("no stream");
  }
  $("#startScore").on("click", async () => {
    const resourceID = $("#pitchResourceID").val();
    startScore(resourceID);
  });
  $("#stopScore").on("click", async () => {
    const zcm = getZCM();
    const resourceID = $("#pitchResourceID").val();
    zcm.stopScore(resourceID);
    isScoreRunning = false;
    isScorePaused = false;
    pitchView.reset();
    pitchView.onPlayLineChange(0, 0);
    if (pitchTimer) clearInterval(pitchTimer);
  });
  $("#pauseScore").on("click", async () => {
    const zcm = getZCM();
    const resourceID = $("#pitchResourceID").val();
    zcm.pauseScore(resourceID);
    isScorePaused = true;
    pitchView.onPlayLineChange(0, 0);
  });
  $("#resumeScore").on("click", async () => {
    const zcm = getZCM();
    const resourceID = $("#pitchResourceID").val();
    zcm.resumeScore(resourceID);
    isScorePaused = false;
    pitchView.onPlayLineChange(0, 0);
  });
  $("#resetScore").on("click", async () => {
    const zcm = getZCM();
    const resourceID = $("#pitchResourceID").val();
    zcm.resetScore(resourceID);
    pitchView.reset();
    pitchView.setStandardPitch(curPitch);
    pitchView.onPlayLineChange(0, 0);
  });
  const getKrcFunc = async (token) => {
    const zcm = getZCM();
    const { errorCode, lyrics } = await zcm.getKrcLyricByToken(token);
    console.warn("zc.cm getKrcLyricByToken", { errorCode, lyrics });
    handleLyrics(lyrics);
  };
  $("#getKrc").on("click", async () => {
    getKrcFunc($("#krcToken").val());
  });
  $("#getLrc").on("click", async () => {
    const zcm = getZCM();
    const { errorCode, lyrics } = await zcm.getLrcLyric($("#songID").val(), parseInt($("#vendorID").val()));
    console.warn("zc.cm getLrcLyric", { errorCode, lyrics });
    handleLyrics(lyrics);
  });
  $("#initCopyMusic").on("click", async () => {
    const zcm = getZCM();
    const userID = $("#userID").val()
    console.warn("zc.cm 开始初始化版权音乐", userID);
    const res = await zcm.initCopyrightedMusic({ user: { userID: userID, userName: userID } });
    console.warn("zc.cm 初始化完成", res);
    if (res === 0) {
      $("#initCopyMusicText").text("初始化完成")
    } else {
      $("#initCopyMusicText").text("初始化失败： " + res)
    }
  });
  $("#destroyCopyMusic").on("click", async () => {
    getEngine().destroyCopyrightedMusic()
    console.warn("zc.cm 反初始化完成");
    $("#initCopyMusicText").text("未初始化")
  });
  $("#loginAndInitCopyMusic").on("click", async () => {
    const loginSuc = await enterRoom();
    if (loginSuc) $("#initCopyMusic").trigger("click")
  })
  $("#sendExtendedRequest").on("click", async () => {
    const zcm = getZCM();
    const paramsStr = $("#extendedParams").val();
    try {
      const params = JSON.parse(paramsStr) || {};
      const res = await zcm.sendExtendedRequest($("#extendedCmd").val(), params);
      console.warn("zc.cm sendExtendedRequest", params, res);
      $("#extendedResult").val(JSON.stringify(res));
    }
    catch (error) {
      alert("参数格式错误");
      throw error;
    }
  });
  let isOrigin = true;
  function playUrls(urls, segment) {
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    if (urls.length > 1) {
      // 0是伴奏 1是原曲
      songPlayer.src = urls[1];
      accompanyPlayer.src = urls[0];
      // 通过控制标签 muted 来切换音轨
      songPlayer.muted = !isOrigin;
      accompanyPlayer.muted = !!isOrigin;

      if (segment && segment.start) {
        console.warn("seek to ", segment);
        songPlayer.currentTime = segment.start / 1000;
        accompanyPlayer.currentTime = segment.start / 1000;
      }
    }
    else if (urls.length === 1) {
      // 原歌曲只有一个 url
      accompanyPlayer.src = "";
      songPlayer.src = urls[0];
    }
    songPlayer.currentTime = 0;
    accompanyPlayer.currentTime = 0;
  }

  const downloadSongFunc = async (resource_id) => {
    const zcm = getZCM();
    let outUrls = [];
    $(`#resourceList #resource_${resource_id} .downloading`).show();
    const { errorCode, urls } = await zcm.download(resource_id);
    $(`#resourceList #resource_${resource_id} .downloading`).hide();
    console.warn("download music ", resource_id, {
      errorCode,
      urls
    });
    if (errorCode !== 0) {
      $(`#resourceList #resource_${resource_id} .handlerBox`).hide();
      alert("下载失败：" + errorCode);
    } else {
      outUrls = urls;
      $(`#resourceList #resource_${resource_id} .handlerBox`).show();
    }
    return outUrls;
  };

  async function handleRequestResource(isShared = false) {
    const zcm = getZCM();
    const songID = $("#songID").val();
    const resourceType = parseInt($("#resourceType").val());
    let vendorID = $("#vendorID").val();
    let masterID = $("#masterID").val() || undefined;
    let mode = parseInt($("#billMode").val()); mode = isNaN(mode) ? undefined : mode
    let sceneID = $("#sceneID").val() || undefined; sceneID = isNaN(sceneID) ? undefined : sceneID;
    let segment = {};
    let resourceList = [];
    vendorID = vendorID ? parseInt(vendorID) : undefined;
    try {
      let res;
      const params = { songID, vendorID, masterID, mode, sceneID }
      if (isShared) {
        res = await zcm.getSharedResource(params, resourceType);
      } else {
        res = await zcm.requestResource(params, resourceType);
      }
      console.warn("zc.cm requestResource ", params, res);
      if (res.errorCode === 0) {

        const {
          segment_begin,
          segment_end,
          other_segments,
          krc_token
        } = res.resource.data;
        let start = segment_begin,
          end = segment_end;
        if (other_segments) {
          start = other_segments[0].start;
          end = other_segments[0].end;
        }
        segment = { start, end };

        resourceList = res.resource.data.resources.map((item) => ({
          ...item,
          krc_token
        }));
        resourceList.forEach(async (item) => {
          let outUrls = [];
          const content = `
          <div class="resourceItem" id="resource_${item.resource_id}">
            <input class="resourceId" placeholder="songID" value="${item.resource_id}">
            <button class="downloadResourceButton" data-id="${item.resource_id}" class="btn btn-primary">下载</button>
            <span class="downloading" style="display: none;">下载中。。。</span>
            <div class="handlerBox" style="display: none;">
              <button class="loadResourceButton" data-id="${item.resource_id}" class="btn btn-primary">加载</button>
            </div>
          </div>
          `;
          $("#resourceList").append(content);
          setTimeout(() => {
            const query = `#resourceList #resource_${item.resource_id} .downloadResourceButton`;
            console.log("zc.cm dom 元素 绑定点击", $(query));
            $(`#resourceList #resource_${item.resource_id} .downloadResourceButton`).on("click", async (e) => {

              outUrls = await downloadSongFunc(item.resource_id);
            });
            $(`#resourceList #resource_${item.resource_id} .loadResourceButton`).on("click", async () => {
              console.log("zc.cm play resource", item.resource_id, outUrls);
              playUrls(outUrls, segment);
            });
          }, 100);
        });
      }
      $("#requestResourceResult").val(JSON.stringify(res));
      return {
        resourceList,
        segment
      };
    } catch (error) {
      alert("异常出错， 有BUG");
      throw error;
    }
  }
  $("#requestResource").on("click", async () => {
    handleRequestResource()
  });
  $("#requestSharedResource").on("click", async () => {
    handleRequestResource(true)
  });
  $("#mixingSong").on("click", () => {
    const zg = getEngine();
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    songPlayer.muted = !isOrigin;
    accompanyPlayer.muted = !!isOrigin;
    // songPlayer.currentTime = 0;
    // accompanyPlayer.currentTime = 0;
    if (songPlayer && accompanyPlayer) {
      const result = zg.startMixingAudio(localStreamMap[$("#roomId").val()], [
        songPlayer,
        accompanyPlayer
      ]);
      // if (result) {
      //   songPlayer.play();
      //   accompanyPlayer.play();
      // }
      console.warn("zc.cm startMixingAudio", result);
    }
  });
  $("#stopMixingSong").on("click", () => {
    const zg = getEngine();
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    songPlayer.muted = !isOrigin;
    accompanyPlayer.muted = !!isOrigin;
    if (songPlayer && accompanyPlayer) {
      const result = zg.stopMixingAudio(localStreamMap[$("#roomId").val()], [
        songPlayer,
        accompanyPlayer
      ]);
      // if (result) {
      //   songPlayer.pause();
      //   accompanyPlayer.pause();
      // }
      console.warn("zc.cm stopMixingAudio", result);
    }
  });
  $("#switchSongTrack").on("click", () => {
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    isOrigin = !isOrigin;
    songPlayer.muted = !isOrigin;
    accompanyPlayer.muted = !!isOrigin;
  });
  $("#clearSongCache").on("click", () => {
    getZCM().clearCache();
    console.warn("zc.cm clearCache 清除所有音频缓存");
  });

  $("#singSongQuick").on("click", async () => {
    const { segment, resourceList } = await handleRequestResource();
    const res = resourceList[0];
    const urls = await downloadSongFunc(res.resource_id);
    $("#krcToken").val(res.krc_token);
    await getKrcFunc(res.krc_token);
    $("#pitchResourceID").val(res.resource_id);
    await getPitchFunc(res.resource_id);
    await startScore(res.resource_id);
    playUrls(urls, segment);
  });

  $("#resetResourceList").on("click", () => {
    $("#resourceList").html("")
    console.warn("zc.cm resetResourceList");
  });
  $("#micVolumeInput").on("change", () => {
    const value = $("#micVolumeInput").val()
    getEngine().setCaptureVolume(localStreamMap[$("#roomId").val()], parseInt(value))
  })
  $("#songVolumeInput").on("change", () => {
    const value = parseInt($("#songVolumeInput").val())
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    songPlayer.volume = value / 100;
    accompanyPlayer.volume = value / 100;
    getEngine().setMixingAudioVolume(publishStreamId, value, songPlayer);
    getEngine().setMixingAudioVolume(publishStreamId, value, accompanyPlayer);
  })
  $("#playSongPlayer").on("click", () => {
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    // 同时开始播放两个音轨
    songPlayer.play();
    accompanyPlayer.play();
  })
  $("#pauseSongPlayer").on("click", () => {
    const songPlayer = document.getElementById("copySongPlayer");
    const accompanyPlayer = document.getElementById("copyAccompanyPlayer");
    // 同时开始播放两个音轨
    songPlayer.pause();
    accompanyPlayer.pause();
  })
  $("#setMixingAudioDelay").on("click", () => {
    console.warn("setMixingAudioDelay", parseInt($("#mixingAudioDelay").val()))
    getEngine().setEngineConfig({
      mixingAudioDelay: parseInt($("#mixingAudioDelay").val())
    })
  })
  getEngine().on("publisherStateUpdate", ({ state }) => {
    publishState = state
  })
  getEngine().on("playerRecvSEI", (streamID, uintArray) => {
    let offset = 0;
    // 接收到的 SEI 内容的前 4 bytes 代表发送的 SEI 类型， 将其转换为 number，
    // 1004 代表 payload type = 5， 1005 代表 payload type = 243
    let mediaSideInfoType = 0;
    mediaSideInfoType = uintArray[offset++] << 24;
    mediaSideInfoType |= uintArray[offset++] << 16;
    mediaSideInfoType |= uintArray[offset++] << 8;
    mediaSideInfoType |= uintArray[offset++];
    // 根据发送的 SEI， 解出 SEI 的内容，示例如下：
    try {
      const json = JSON.parse(new TextDecoder().decode(uintArray.slice(4)));
      if (json) {
        lyricView.setCurrentTimeMillis(json.KEY_PROCESS_IN_MS * 1000);
      }
      // console.warn("zc.cm playerRecvSEI", json);
    }
    catch (error) {
      console.warn("zc.cm playerRecvSEI error", error, new TextDecoder().decode(uintArray.buffer));
    }
  });
  // $("#resourceList .downloadResourceButton").on("click", (e: any) => {
  //   console.log("zc.cm download", e);
  // });
}
// // @ts-ignore
// const zcm = cm.zcm;
// const code = await zcm.init({ user: { userID } });
// if (code === 0) {
//   const listRes = await zcm.sendExtendedRequest("/tag/list", {});
//   console.warn("zc.cm ktvvv", listRes.result.data);
//   const { result } = listRes;
//   const group = result.data?.groups[0];
//   const { tag_id } = group.tags[0];
//   if (group) {
//     const songRes = await zcm.sendExtendedRequest("/tag/song", {
//       tag_id: "84",
//       page: 1,
//       filter: [1, 3]
//     });
//     console.warn("zc.cm ktvvv", songRes.result.data);
//   }
//   const source = await zcm.requestResource("28094458", 2);
//   console.warn("zc.cm ktvvv src", source);
//   // 此生不换"28094458"
// }
